# 如果你是Python36。请删除37、38、39的pyd文件，其他版本同理
import peewee
import datetime
import os
import openai


import time
import json
import requests
import base64

import os
# import openai
import asyncio
from EdgeGPT import Chatbot


# async def EDGE(info):
#     bot = Chatbot(cookiePath='./cookie.json')
#     INFO = ((await bot.ask(prompt=info)))
#     try:
#         print(INFO)
#         answer = INFO['item']['messages'][1]['text'].replace('^', '').replace('\n', '').replace('必应', '老胡').replace('Bing', '老胡')
#         try:
#             url = INFO['item']['messages'][1]['adaptiveCards'][0]['body'][1]['text'].replace('Learn more: ', '参考链接:\n').replace(') [', ')\n[')
#             print(answer.replace('^', ''))
#             print(url)
#             INFO = answer + '\n' + url
#         except:
#             INFO = answer
#     except:
#         INFO = '出现错误，稍后再试。\n或联系管理员。'
#     await bot.close()
#     return INFO








# os.environ["http_proxy"] = "http://127.0.0.1:10809"
# os.environ["https_proxy"] = "http://127.0.0.1:10809"
proxies = {'http': "http://127.0.0.1:10809",
            'https': "http://127.0.0.1:10809"}
openai.proxy = proxies

openai.api_key = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

db = peewee.SqliteDatabase('Bot.db')

class BaseModel(peewee.Model):
    class Meta:
        database = db

class User(BaseModel):
    wx_num = peewee.CharField(verbose_name='微信账户', unique=True)
    name = peewee.CharField(verbose_name='微信昵称')
    duihuacishu = peewee.IntegerField(verbose_name='对话次数', default=5)

class Bot(BaseModel):
    creattime = peewee.DateTimeField(verbose_name='创建时间', default=str(datetime.datetime.now()))
    user = peewee.ForeignKeyField(User, backref='bot')


class DuihuaList(BaseModel):
    botid = peewee.ForeignKeyField(Bot, backref='duihualist')
    userid = peewee.ForeignKeyField(User, backref='duihualist')


class Duihua(BaseModel):
    role = peewee.CharField(verbose_name='角色')
    time = peewee.DateTimeField(verbose_name='消息时间', default=str(datetime.datetime.now()))
    botid = peewee.ForeignKeyField(Bot, backref='duihua')
    userid = peewee.ForeignKeyField(User, backref='duihua')
    info = peewee.TextField(verbose_name='消息内容')
    duihualist = peewee.ForeignKeyField(DuihuaList, backref='duihua')




db.connect()
# db.create_tables([User, Bot, Duihua, DuihuaList])


def AI(info):

    completion = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=info
    )
    answer = completion.choices[0].message['content']
    return answer

class Person():
    def __init__(self, wx_num):
        self.user = User.get(User.wx_num == wx_num)
        self.bot = Bot.create(user = self.user)
        self.cishu = self.user.duihuacishu * 2 +1

    def creat_duihualist(self):
        self.duihualist = DuihuaList.create(botid=self.bot, userid=self.user)
        Duihua.create(role='system', botid = self.bot, userid = self.user, info = 'You are a helpful assistant.You name is 小胡' ,duihualist = self.duihualist)

    def ask(self, info):
        self.duihualist = DuihuaList.select().order_by(DuihuaList.id.desc()).get()
        count = Duihua.select().where(Duihua.duihualist == self.duihualist).count()
        if count < self.cishu:
            Duihua.create(role='user', botid = self.bot, userid = self.user, info = info ,duihualist = self.duihualist)
            message = Duihua.select().where(Duihua.duihualist == self.duihualist)
            INFO = []
            for each in message:
                INFO.append({'role': each.role, 'content': each.info})
            time_1 = time.time()
            answer = AI(INFO)
            Duihua.create(role='assistant', botid = self.bot, userid = self.user, info = answer ,duihualist = self.duihualist)
            time_2 = str(int(time.time()-time_1))
            return_info = answer + '\n'+'*'*10 +'\n' + '对话次数:'+ str(int((count-1)/2+1)) + '/' + str(self.user.duihuacishu) + '\n' + '耗时:' + time_2 + '秒'
        else:
            return_info = '本轮对话已达上限,请重开对话,或联系管理员增加额度.'

        return return_info




async def edgeAI(info):
    INFO = ((await bot.ask(prompt=info)))
    try:
        print(INFO)
        answer = INFO['item']['messages'][1]['text'].replace('^', '').replace('\n', '').replace('必应', '老胡').replace('Bing', '老胡')
        try:
            url = INFO['item']['messages'][1]['adaptiveCards'][0]['body'][1]['text'].replace('Learn more: ', '参考链接:\n').replace(') [', ')\n[')
            print(answer.replace('^', ''))
            print(url)
            INFO = answer + '\n' + url
        except:
            INFO = answer
    except:
        INFO = '出现错误，请稍后再试。\n或联系管理员。'
    await bot.close()
    return INFO


class edge_Person():
    def __init__(self, wx_num):
        self.user = User.get(User.wx_num == wx_num)
        self.bot = Bot.create(user = self.user)
        self.cishu = self.user.duihuacishu *2 + 1

    def creat_duihualist(self):
        self.duihualist = DuihuaList.create(botid = self.bot, userid = self.user)

    def ask(self, info):
        self.duihualist = DuihuaList.select().order_by(DuihuaList.id.desc()).get()
        count = Duihua.select().where(Duihua.duihualist == self.duihualist).count()
        if count < self.cishu:
            Duihua.create(role='user', botid = self.bot, userid = self.user, info = info, duihualist=self.duihualist)
            time_1 = time.time()
            answer = asyncio.run(edgeAI(info))
            Duihua.create(role='assistant', botid = self.bot, userid = self.user, info = answer, duihualist = self.duihualist)
            time_2 = str(int(time.time() - time_1))
            return_info = answer + '\n'+'*'*10 +'\n' + '对话次数:'+ str(int((count-1)/2+1)) + '/' + str(self.user.duihuacishu) + '\n' + '耗时:' + time_2
        else:
            return_info = '本轮对话已达上限,请重开对话,或联系管理员增加额度。'

        return return_info



# AA = Person(wx_num='222')
# AA.creat_duihualist()
#
# while True:
#     info = input('输入问题?\n')
#     print(AA.ask(info))























from WeChatPYAPI import WeChatPYApi

import time
import logging
from queue import Queue
import os



# 当前目录路径
BASE_DIR = os.path.dirname(os.path.abspath(__file__))


logging.basicConfig(level=logging.INFO)  # 日志器
msg_queue = Queue()  # 消息队列


def on_message(msg):
    """消息回调，建议异步处理，防止阻塞"""
    print(msg)
    msg_queue.put(msg)


def on_exit(wx_id):
    """退出事件回调"""
    print("已退出：{}".format(wx_id))


def main():

    w = WeChatPYApi(msg_callback=on_message, exit_callback=on_exit, logger=logging)

    # 启动微信
    w.start_wx()
    # w.start_wx(path=os.path.join(BASE_DIR, "login_qrcode.png"))  # 保存登录二维码

    # 这里需要阻塞，等待获取个人信息
    while not w.get_self_info():
        time.sleep(5)

    my_info = w.get_self_info()
    self_wx = my_info["wx_id"]
    print("登陆成功！")
    print(my_info)

    lists = w.pull_list(self_wx=self_wx, pull_type=1)
    print(lists)
    for each in lists:
        try:
            User.create(wx_num = each['wx_id'], name= each['nick_name'])
        except:
            continue

    while True:
        lists = w.pull_list(self_wx=self_wx, pull_type=1)
        print(lists)
        for each in lists:
            try:
                User.create(wx_num=each['wx_id'], name=each['nick_name'])
            except:
                continue
        msg = msg_queue.get()

        if msg["msg_type"] == 1:
            # AA = Person(wx_num=msg['wx_id'])
            if msg['content'][:2] == '小胡':
                AA = Person(wx_num=msg['wx_id'])
                if '创建对话' in msg['content'][:10]:
                    AA.creat_duihualist()
                    w.send_text(
                        self_wx=self_wx,
                        to_wx=msg['wx_id'],
                        msg = '对话创建成功。'
                    )
                else:
                    INFO = AA.ask(msg['content'])
                    w.send_text(
                        self_wx=self_wx,
                        to_wx=msg['wx_id'],
                        msg = INFO
                    )
            elif msg['content'][:2] == '老胡':
                AA = edge_Person(wx_num=msg['wx_id'])
                if '创建对话' in msg['content'][:10]:
                    AA.creat_duihualist()
                    w.send_text(
                        self_wx=self_wx,
                        to_wx=msg['wx_id'],
                        msg='对话创建成功。'
                    )
                else:
                    INFO = AA.ask(msg['content'])
                    w.send_text(
                        self_wx=self_wx,
                        to_wx=msg['wx_id'],
                        msg=INFO
                    )





            elif msg['content'][:2] == '帮助':
                info = '机器人分为两个:“老胡”和“小胡”\n 介绍:\n 老胡:基于NewBing的聊天接口，具有实时联网，全网数据库的优势，缺点是暂无连续对话功能，回复较慢。\n 小胡:基于OpenAI的GPT-3.5-turbo。优点是有连续对话功能，回复相对较快，缺点是无2021年后数据资料。\n 使用方法:\n 老胡:触发条件为“老胡”，\n例:老胡，如何评价电影“流浪地球2”？\n 小胡:触发条件为“小胡”。\n 1.“小胡，创建聊天”，初始化机器人，创建对话。\n 2.连续对话也需附带触发词“小胡”。\n 3.该api为付费接口，且连续对话的资源消耗量指数增加，故限制对话次数为5轮，如需增加，联系管理员。'
                w.send_text(
                    self_wx=self_wx,
                    to_wx=msg['wx_id'],
                    msg = info,
                )

            else:
                info = '指令未识别，输入“帮助”可查看机器人使用方法。'
                w.send_text(
                    self_wx=self_wx,
                    to_wx=msg['wx_id'],
                    msg = info,
                )


if __name__ == '__main__':
    main()

